package com.glsc.ngateway.opmanage.controller;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.glsc.ngateway.common.api.common.dto.PageDataResult;
import com.glsc.ngateway.common.api.common.utils.DateUtil;
import com.glsc.ngateway.common.api.common.utils.JsonUtil;
import com.glsc.ngateway.common.api.common.utils.PageUtil;
import com.glsc.ngateway.common.api.flowable.dto.demand.*;
import com.glsc.ngateway.common.api.flowable.dto.demand.node.ProcessNode;
import com.glsc.ngateway.common.api.flowable.dto.param.ParamCommentDto;
import com.glsc.ngateway.common.api.flowable.dto.param.ParamCreateDto;
import com.glsc.ngateway.common.api.flowable.dto.param.ParamDoTaskDto;
import com.glsc.ngateway.common.api.flowable.dto.param.ParamSearchDto;
import com.glsc.ngateway.common.api.flowable.feign.IFeignFlowableService;
import com.glsc.ngateway.common.api.flowable.resp.*;
import com.glsc.ngateway.common.api.ldap.dto.LdapEhrDeptDto;
import com.glsc.ngateway.common.api.ldap.dto.LdapEhrEmpDto;
import com.glsc.ngateway.common.api.ldap.dto.LdapUserDto;
import com.glsc.ngateway.common.api.ldap.feign.IFeignLdapService;
import com.glsc.ngateway.common.api.ldap.resp.AppEhrResponse;
import com.glsc.ngateway.common.api.platform.resp.PlatformResponse;
import com.glsc.ngateway.common.base.enums.OaHrmresourceStatusEnum;
import com.glsc.ngateway.opmanage.service.DemandService;
import com.glsc.ngateway.opmanage.service.UserService;
import com.glsc.ngateway.opmanage.utils.RequestTool;
import com.glsc.ngateway.opmanage.utils.TokenUtil;
import com.google.common.base.Strings;
import lombok.SneakyThrows;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@RestController
@RequestMapping(value = "/demand")
public class DemandManagementController {

    Logger logger = LoggerFactory.getLogger(this.getClass());

    private static int default_page_number = 1;
    private static int default_page_size = 10;


    @Resource
    IFeignFlowableService feignDemandService;
    @Autowired
    IFeignLdapService feignLdapService;
    @Autowired
    DemandService demandService;

    @Autowired
    TokenUtil tokenUtil;

    @Value("${demand.downloadUrl}")
    String downloadUrl;

    @Resource
    private IFeignLdapService feignEhrService;

    @Resource
    private UserService userService;
    @Resource
    private RequestTool requestTool;

    @RequestMapping(method = RequestMethod.GET, value = "getOaUserToken")
    public PlatformResponse<String> getOaUserToken(@RequestParam(value = "userId", required = true) String userId,
                                                   @RequestParam(value = "systemId", required = true) String systemId) {
        try {
            String result = feignLdapService.getOaUserToken(LdapUserDto.builder()
                    .userName(userId)
                    .systemId(systemId)
                    .build());
            return PlatformResponse.successData(result);
        } catch (Exception e) {
            logger.error("getOaUserToken异常！", e);
            return PlatformResponse.failedMsg(e.getMessage());
        }
    }


    @RequestMapping(method = RequestMethod.GET, value = "getUserInfo")
    public PlatformResponse<DemandManagementDto> getUserInfo(@RequestParam(value = "userId", required = true) String userId) {

        PlatformResponse<DemandManagementDto> ret = null;
        try {
            DemandManagementDto glRequirement = new DemandManagementDto();
            glRequirement.setRqStaff(userId);
            AppEhrResponse<LdapEhrEmpDto> user = feignEhrService.getLdapEhrEmp(userId, null, false);
            //废弃admin和itadmin
            if (("admin").equals(userId) || ("itadmin").equals(userId) || ("devadmin").equals(userId)) {
                glRequirement.setRqDepartment("信息技术总部");
                glRequirement.setRqStaffCName("系统管理员");
            } else {
                if (user != null) {
                    LdapEhrEmpDto map = user.getData();
                    glRequirement.setRqDepartment(map.getTitle());
                    glRequirement.setRqStaffCName(map.getName());
                }
            }
            ret = PlatformResponse.successData(glRequirement);

        } catch (Exception e) {
            ret = PlatformResponse.failedMsg(e.getMessage());
            logger.error("getUserInfo异常！", e);
        }
        return ret;
    }

    private Object map2JavaBean(Class<?> clazz, Map<String, String> map) throws Exception {
        Object javabean = clazz.newInstance(); // 构建对象
        Method[] methods = clazz.getMethods(); // 获取所有方法
        for (Method method : methods) {
            if (method.getName().startsWith("set")) {
                String field = method.getName(); // 截取属性名
                field = field.substring(field.indexOf("set") + 3);
                field = field.toLowerCase().charAt(0) + field.substring(1);
                if (map.containsKey(field)) {
                    method.invoke(javabean, map.get(field));
                }
            }
        }
        return javabean;
    }

    @RequestMapping(method = RequestMethod.GET, value = "getUserList")
    public PlatformResponse<List<ResponseUserListDto>> getUserList(
            @RequestParam(value = "department", required = false) String department,
            @RequestParam(value = "findAll", required = false) boolean findAll
    ) {
        try {
            AppEhrResponse<List<LdapEhrEmpDto>> user = feignLdapService.getAllEmps();
            if (Objects.isNull(user) || CollectionUtil.isEmpty(user.getData())) {
                return PlatformResponse.successData(Collections.EMPTY_LIST);
            }
            //过滤在职人员
            if (!findAll) {
                user.setData(user.getData().stream().filter(u -> OaHrmresourceStatusEnum.isAlive(u.getStatus())).collect(Collectors.toList()));
            }
            if (CollectionUtil.isEmpty(user.getData())) {
                return PlatformResponse.successData(Collections.EMPTY_LIST);
            }
            //获取所有部门
            AppEhrResponse<List<LdapEhrDeptDto>> depts = feignLdapService.getAllDept();
            if (Objects.isNull(depts) || CollectionUtil.isEmpty(depts.getData())) {
                return PlatformResponse.successData(Collections.EMPTY_LIST);
            }
            //支持多级部门
            Set<String> depSet;
            if (StringUtils.isBlank(department)) {
                depSet = depts.getData().stream()
                        .map(LdapEhrDeptDto::getDtitle)
                        .collect(Collectors.toSet());
            } else {
                depSet = new HashSet<>();
                Map<String, List<LdapEhrDeptDto>> parentMap = depts.getData().stream()
                        .filter(d -> StringUtils.isNotBlank(d.getAtitle()))
                        .collect(Collectors.groupingBy(LdapEhrDeptDto::getAtitle));
                //bfs筛选
                Queue<LdapEhrDeptDto> que = new LinkedList<>(parentMap.get(department));
                while (!que.isEmpty()) {
                    LdapEhrDeptDto poll = que.poll();
                    depSet.add(poll.getDtitle());
                    if (parentMap.containsKey(poll.getDtitle())) {
                        que.addAll(parentMap.get(poll.getDtitle()));
                    }
                }
            }
            Map<Integer, List<LdapEhrEmpDto>> userMap = user.getData()
                    .stream()
                    .filter(e -> !StringUtils.isEmpty(e.getTitle()) && Objects.nonNull(e.getDepid())
                            && (StringUtils.isEmpty(department) || depSet.contains(e.getTitle())))
                    .collect(Collectors.groupingBy(LdapEhrEmpDto::getDepid));

            Map<Integer, LdapEhrDeptDto> deptMap = depts.getData().stream().collect(Collectors.toMap(LdapEhrDeptDto::getDepid, Function.identity(), (K1, K2) -> K2));
            List<ResponseUserListDto> reslist = userMap.entrySet().stream()
                    .map(m -> {
                        if (!deptMap.containsKey(m.getKey())) {
                            return null;
                        }
                        LdapEhrDeptDto deptinfoEntity = deptMap.get(m.getKey());
                        ResponseUserListDto res = new ResponseUserListDto();
                        res.setTitle(deptinfoEntity.getDtitle());
                        res.setValue(String.valueOf(deptinfoEntity.getDepid()));
                        res.setKey(String.valueOf(deptinfoEntity.getDepid()));
                        List<ResponseUserListSubDto> list = m.getValue().stream()
                                .map(f -> ResponseUserListSubDto.builder()
                                        .title(f.getName())
                                        .value(f.getBadge())
                                        .key(f.getBadge())
                                        .department(deptinfoEntity.getDtitle())
                                        .departmentValue(res.getValue())
                                        .build())
                                .sorted(Comparator.comparing(ResponseUserListSubDto::getTitle))
                                .collect(Collectors.toList());
                        res.setChildren(list);
                        return res;
                    })
                    .filter(Objects::nonNull)
                    .sorted(Comparator.comparing(ResponseUserListDto::getTitle))
                    .collect(Collectors.toList());
            return PlatformResponse.successData(reslist);
        } catch (Exception e) {
            logger.error("getUserList异常！", e);
            return PlatformResponse.failedMsg("操作失败", e.getMessage());
        }
    }

    @SneakyThrows
    @RequestMapping(method = RequestMethod.GET, value = "getDepartmentList")
    public PlatformResponse<JSONArray> getDepartmentList(@RequestParam(value = "department", required = false) String department,
                                                         @RequestParam(value = "groupBy", required = false) String groupBy,
                                                         @RequestParam(value = "findAll", required = false) boolean findAll ){
        AppEhrResponse<List<LdapEhrDeptDto>> depts = feignEhrService.getAllDept();
        //过滤无效
        if (!findAll) {
            depts.setData(depts.getData().stream().filter(u -> !"1".equals(u.getCanceled())).collect(Collectors.toList()));
        }
        if (Objects.isNull(depts) || CollectionUtil.isEmpty(depts.getData())) {
            return PlatformResponse.successData(new JSONArray());
        }
        return PlatformResponse.successData(userService.convertToTreeJson(depts.getData(), department, groupBy));
    }

    /**
     * 创建一个新的需求
     *
     * @param request
     * @param glRequirement
     * @return
     */
    @RequestMapping(method = RequestMethod.POST, value = "createRq")
    public PlatformResponse<String> createRq(HttpServletRequest request, @RequestBody DemandManagementDto glRequirement) {
        PlatformResponse<String> ret;
        try {
            //1.调用网关系统启动流程，并存储需求,所有需求都只记录在网关系统
            ParamCreateDto paramCreateDto = new ParamCreateDtoBuilder().setReqStartElemets(glRequirement).build();
            FlowableResponse<ResponseCreateDto> creatflowRet = feignDemandService.create(paramCreateDto);

            return creatflowRet.getStatus() == 0 ? PlatformResponse.successData(creatflowRet.getData().getProcessId())
                    : PlatformResponse.failedMsg(creatflowRet.getMsg());

        } catch (Exception e) {
            logger.error("createRq异常！", e);
            return PlatformResponse.failedMsg(e.getMessage());
        }
    }


    private String getFlowableErrMsg(FlowableResponse nwret) {
        StringBuilder sb = new StringBuilder("Flowable异常：");
        sb.append(nwret.getMsg());
        if (nwret.getData() != null && nwret.getData() instanceof ResponseMsgDto) {
            sb.append("---").append(((ResponseMsgDto) nwret.getData()).getMsg());
        }
        return sb.toString();
    }


    /**
     * "需求提交"节点操作
     *
     * @param request
     * @param glRequirement
     * @return
     */
    @RequestMapping(method = RequestMethod.POST, value = "submitTask")
    public PlatformResponse<?> submitTask(HttpServletRequest request, @RequestBody DemandManagementDto glRequirement) {
        PlatformResponse<?> ret;
        try {
            //根据processId获取当前节点taskId
            String[] taskIdAndTitleAndSysid = demandService.getCurrentTaskIdAndTitleAndSysid(glRequirement.getRqId());
            if (taskIdAndTitleAndSysid == null) {
                ret = PlatformResponse.failedMsg("未获取到当前流程节点信息");
            }

            ParamDoTaskDto nwreq = new ParamDoTaskDtoBuilder(taskIdAndTitleAndSysid[0], taskIdAndTitleAndSysid[1], taskIdAndTitleAndSysid[2]).setSubmit(glRequirement).build();

            FlowableResponse<ResponseMsgDto> nwret = feignDemandService.doTask(nwreq);
            if (nwret.getStatus() != 0) {
                ret = PlatformResponse.failedMsg(getFlowableErrMsg(nwret));
            } else {
                ret = PlatformResponse.success();
            }

        } catch (Exception e) {
            ret = PlatformResponse.failedMsg(e.getMessage());
            logger.error("submitTask异常！", e);
        }

        return ret;
    }


    /**
     * "需求确认"节点操作
     */
    @RequestMapping(method = RequestMethod.POST, value = "confirmTask")
    public PlatformResponse<?> confirmTask(HttpServletRequest request, @RequestBody ConfirmTaskReq passConfirmReq) {
        PlatformResponse<?> ret;
        try {
            //根据processId获取当前节点taskId
            String[] taskIdAndTitle = demandService.getCurrentTaskIdAndTitleAndSysid(passConfirmReq.getRqId());
            if (taskIdAndTitle == null) {
                ret = PlatformResponse.failedMsg("未获取到当前流程节点信息");
            }

            ParamDoTaskDto nwreq = new ParamDoTaskDtoBuilder(taskIdAndTitle[0], taskIdAndTitle[1], taskIdAndTitle[2]).setConfirmTask(passConfirmReq).build();

            FlowableResponse<ResponseMsgDto> nwret = feignDemandService.doTask(nwreq);
            if (nwret.getStatus() != 0) {
                ret = PlatformResponse.failedMsg(getFlowableErrMsg(nwret));
            } else {
                ret = PlatformResponse.success();
            }
        } catch (Exception e) {
            ret = PlatformResponse.failedMsg(e.getMessage());
            logger.error("confirmTask异常！", e);
        }
        return ret;
    }


    /**
     * "高级审批"节点操作
     */
    @RequestMapping(method = RequestMethod.POST, value = "advanceTask")
    public PlatformResponse<?> advanceTask(HttpServletRequest request, @RequestBody AdvanceTaskReq advanceTaskReq) {
        PlatformResponse<?> ret;
        try {
            //根据processId获取当前节点taskId

            String[] taskIdAndTitle = demandService.getCurrentTaskIdAndTitleAndSysid(advanceTaskReq.getRqId());
            if (taskIdAndTitle == null) {
                ret = PlatformResponse.failedMsg("未获取到当前流程节点信息");
            }

            ParamDoTaskDto nwreq = new ParamDoTaskDtoBuilder(taskIdAndTitle[0], taskIdAndTitle[1], taskIdAndTitle[2]).setAdvanceTask(advanceTaskReq).build();

            FlowableResponse<ResponseMsgDto> nwret = feignDemandService.doTask(nwreq);
            if (nwret.getStatus() != 0) {
                ret = PlatformResponse.failedMsg(getFlowableErrMsg(nwret));
            } else {
                ret = PlatformResponse.success();
            }

        } catch (Exception e) {
            ret = PlatformResponse.failedMsg(e.getMessage());
            logger.error("advanceTask异常！", e);
        }

        return ret;
    }


    /**
     * "相关人员会签"节点操作
     */
    @RequestMapping(method = RequestMethod.POST, value = "signatureTask")
    public PlatformResponse<?> signatureTask(HttpServletRequest request, @RequestBody SignatureTaskReq signatureTaskReq) {
        PlatformResponse<?> ret;
        try {
            //根据processId获取当前节点taskId
            String[] taskIdAndTitle = demandService.getCurrentTaskIdAndTitleAndSysid(signatureTaskReq.getRqId());
            if (taskIdAndTitle == null) {
                ret = PlatformResponse.failedMsg("未获取到当前流程节点信息");
            }

            ParamDoTaskDto nwreq = new ParamDoTaskDtoBuilder(signatureTaskReq.getTaskId(), taskIdAndTitle[1], taskIdAndTitle[2]).setSignatureTask(signatureTaskReq).build();

            FlowableResponse<ResponseMsgDto> nwret = feignDemandService.doTask(nwreq);
            if (nwret.getStatus() != 0) {
                ret = PlatformResponse.failedMsg(getFlowableErrMsg(nwret));
            } else {
                ret = PlatformResponse.success();
            }

        } catch (Exception e) {
            ret = PlatformResponse.failedMsg(e.getMessage());
            logger.error("signatureTask异常！", e);
        }

        return ret;
    }


    /**
     * "OA会签"节点操作
     */
    @RequestMapping(method = RequestMethod.POST, value = "createoaTask")
    public PlatformResponse<?> createoaTask(HttpServletRequest request, @RequestBody CreateoaTaskReq createoaTaskReq) {
        PlatformResponse<?> ret;
        try {
            //根据processId获取当前节点taskId
            String[] taskIdAndTitle = demandService.getCurrentTaskIdAndTitleAndSysid(createoaTaskReq.getRqId());
            if (taskIdAndTitle == null) {
                ret = PlatformResponse.failedMsg("未获取到当前流程节点信息");
            }

            ParamDoTaskDto nwreq = new ParamDoTaskDtoBuilder(taskIdAndTitle[0], taskIdAndTitle[1], taskIdAndTitle[2]).setCreateoaTask(createoaTaskReq).build();

            FlowableResponse<ResponseMsgDto> nwret = feignDemandService.doTask(nwreq);
            if (nwret.getStatus() != 0) {
                ret = PlatformResponse.failedMsg(getFlowableErrMsg(nwret));
            } else {
                ret = PlatformResponse.success();
            }

        } catch (Exception e) {
            ret = PlatformResponse.failedMsg(e.getMessage());
            logger.error("createoaTask异常！", e);
        }

        return ret;
    }


    /**
     * "排期"节点操作
     */
    @RequestMapping(method = RequestMethod.POST, value = "arrangeTask")
    public PlatformResponse<?> arrangeTask(HttpServletRequest request, @RequestBody ArrangeTaskReq arrangeTaskReq) {
        PlatformResponse<?> ret;
        try {
            //根据processId获取当前节点taskId

            String[] taskIdAndTitle = demandService.getCurrentTaskIdAndTitleAndSysid(arrangeTaskReq.getRqId());
            if (taskIdAndTitle == null) {
                ret = PlatformResponse.failedMsg("未获取到当前流程节点信息");
            }

            ParamDoTaskDto nwreq = new ParamDoTaskDtoBuilder(taskIdAndTitle[0], taskIdAndTitle[1], taskIdAndTitle[2]).setArrangeTaskReq(arrangeTaskReq).build();

            FlowableResponse<ResponseMsgDto> nwret = feignDemandService.doTask(nwreq);
            if (nwret.getStatus() != 0) {
                ret = PlatformResponse.failedMsg(getFlowableErrMsg(nwret));
            } else {
                ret = PlatformResponse.success();
            }

        } catch (Exception e) {
            ret = PlatformResponse.failedMsg(e.getMessage());
            logger.error("arrangeTask异常！", e);
        }

        return ret;
    }


    /**
     * "上线"节点操作
     */
    @RequestMapping(method = RequestMethod.POST, value = "onlineTask")
    public PlatformResponse<?> onlineTask(HttpServletRequest request, @RequestBody OnlineTaskReq onlineTaskReq) {
        PlatformResponse<?> ret;
        try {
            //根据processId获取当前节点taskId
            String[] taskIdAndTitle = demandService.getCurrentTaskIdAndTitleAndSysid(onlineTaskReq.getRqId());
            if (taskIdAndTitle == null) {
                ret = PlatformResponse.failedMsg("未获取到当前流程节点信息");
            }

            //有可能有的开发人员已经处理过该节点，需要把上线要素进行合并
            FlowableDemandDto rqmt = demandService.getRmptInfo(onlineTaskReq.getRqId());
            List<OnlineInf> oldinfo = new ArrayList<OnlineInf>();
            if (!StringUtils.isEmpty(rqmt.getOnlineinfo())) {
                oldinfo = (List<OnlineInf>) JsonUtil.str2Obj(rqmt.getOnlineinfo(), List.class);
            }

            ParamDoTaskDto nwreq = new ParamDoTaskDtoBuilder(onlineTaskReq.getTaskId(), taskIdAndTitle[1], taskIdAndTitle[2]).setOnlineTaskReq(oldinfo, onlineTaskReq).build();

            FlowableResponse<ResponseMsgDto> nwret = feignDemandService.doTask(nwreq);
            if (nwret.getStatus() != 0) {
                ret = PlatformResponse.failedMsg(getFlowableErrMsg(nwret));
            } else {
                ret = PlatformResponse.success();
            }

        } catch (Exception e) {
            ret = PlatformResponse.failedMsg(e.getMessage());
            logger.error("onlineTask异常！", e);
        }

        return ret;
    }


    /**
     * "验证"节点操作
     */
    @RequestMapping(method = RequestMethod.POST, value = "checkTask")
    public PlatformResponse<?> checkTask(HttpServletRequest request, @RequestBody CheckTaskReq checkTaskReq) {
        PlatformResponse<?> ret;
        try {
            //根据processId获取当前节点taskId

            String[] taskIdAndTitle = demandService.getCurrentTaskIdAndTitleAndSysid(checkTaskReq.getRqId());
            if (taskIdAndTitle == null) {
                ret = PlatformResponse.failedMsg("未获取到当前流程节点信息");
            }

            ParamDoTaskDto nwreq = new ParamDoTaskDtoBuilder(taskIdAndTitle[0], taskIdAndTitle[1], taskIdAndTitle[2]).setCheckTaskReq(checkTaskReq).build();

            FlowableResponse<ResponseMsgDto> nwret = feignDemandService.doTask(nwreq);
            if (nwret.getStatus() != 0) {
                ret = PlatformResponse.failedMsg(getFlowableErrMsg(nwret));
            } else {
                ret = PlatformResponse.success();
            }

        } catch (Exception e) {
            ret = PlatformResponse.failedMsg(e.getMessage());
            logger.error("checkTask异常！", e);
        }
        return ret;
    }


    /**
     * @param request
     * @param pageNumber
     * @param pageSize
     * @param userId        用户
     * @param rqListType    需求结果集类型
     * @param title         过滤条件：需求标题
     * @param beginDate     过滤条件：需求创建日期
     * @param endDate       过滤条件：需求创建日期
     * @param finishFlag    过滤条件：需求是否结束 0：已结束  1：未结束
     * @param createProject 系统
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "listRq")
    public PlatformResponse<Page<DemandManagementDto>> listRq(
            HttpServletRequest request,
            @RequestParam(value = "pageNumber", required = false) Integer pageNumber,
            @RequestParam(value = "pageSize", required = false) Integer pageSize,
            @RequestParam(value = "userId", required = false) String userId,
            @RequestParam(value = "rqListType", required = false) RqListType rqListType,
            @RequestParam(value = "title", required = false) String title,
            @RequestParam(value = "beginDate", required = false) String beginDate,
            @RequestParam(value = "endDate", required = false) String endDate,
            @RequestParam(value = "finishFlag", required = false) String finishFlag,
            @RequestParam(value = "createProject", required = false) String createProject
    ) {
        String accountFromRequest = requestTool.getAccountFromRequest(request);
        logger.info("通过token获取当前用户账户:" + accountFromRequest);

        PlatformResponse<Page<DemandManagementDto>> ret;

        try {

            if (pageNumber == null) {
                pageNumber = default_page_number;
            }
            if (pageSize == null) {
                pageSize = default_page_size;
            }
            if (StringUtils.isNotEmpty(finishFlag)) {
                int finishInt = Integer.parseInt(finishFlag);
                finishInt = 1 - finishInt;
                finishFlag = String.valueOf(finishInt);
            }
            /*
             * 根据username和rqListType(待办需求；我的需求；已办需求)从网关查询需求集合
             * ？？？endDate选择2月15，则2月15创建的流程不能被查出来；beginDate选择2月15，则2月15创建的流程可以被查出来
             * ？？？排序条件没有
             * */
            ParamSearchDto paramSearchDto =
                    new ParamSearchDtoBuilder(rqListType, createProject, userId)
                            .setTitle(title)
                            .setBeginDate(DateUtil.getLocalDate(beginDate))
                            .setEndDate(DateUtil.getLocalDate(endDate))
                            .setHasProcessEnd(finishFlag)
                            .build();
            FlowableResponse<PageDataResult<ResponseSituationDto>> queryflowRet;
            if (RqListType.TODO.equals(rqListType)) {
                queryflowRet = feignDemandService.searchDealProcessList(pageNumber, pageSize, paramSearchDto);
            } else if (RqListType.MINE.equals(rqListType)) {
                queryflowRet = feignDemandService.searchAllOrStartProcessList(pageNumber, pageSize, paramSearchDto);
            } else if (RqListType.RELATED.equals(rqListType)) {
                queryflowRet = feignDemandService.searchInvolveUserProcessList(pageNumber, pageSize, paramSearchDto);
            } else {
                FlowableResponse<List<FlowableAssigneeDto>> response = feignDemandService.findAssigneeByProcessDefinitionKey("DemandManagement", createProject);
                if (response.getStatus() != 0) {
                    return PlatformResponse.failedMsg(response.getMsg());
                }
                List<FlowableAssigneeDto> data = response.getData();
                if (data.stream().anyMatch(e -> e.getAssigneeVariable().equals("manager") && e.getAssigneeName().equals(userId))) {
                    paramSearchDto.setStartUser(null);
                    paramSearchDto.setInvolveUser(null);
                    queryflowRet = feignDemandService.searchAllOrStartProcessList(pageNumber, pageSize, paramSearchDto);
                } else {
                    queryflowRet = feignDemandService.searchInvolveUserProcessList(pageNumber, pageSize, paramSearchDto);
                }
            }

            // 接口返回失败
            if (queryflowRet.getStatus() != 0) {
                return PlatformResponse.failedMsg(queryflowRet.getMsg());
            }

            List<ResponseSituationDto> list = queryflowRet.getData().getList();
//            //过滤了已经结束的需求
//            if ("1".equals(finishFlag)) {
//                list = queryflowRet.getData().getList().stream().filter(r -> !StringUtils.isEmpty(r.getCurrentTaskName())).collect(Collectors.toList());
//            }

            List<String> processIds = list.stream().map(ResponseSituationDto::getProcessId).collect(Collectors.toList());

            FlowableResponse<List<FlowableDemandDto>> demandinfos = feignDemandService.getDemandInfos(processIds);

            Map<String, FlowableDemandDto> demandDtoMap = demandinfos.getData().stream().collect(Collectors.toMap(FlowableDemandDto::getProcessInstanceId, t -> t));

            FlowableResponse<List<ResponseCommentDto>> nwret = feignDemandService.queryCommentsByProcessIds(processIds);

            Map<String, List<ResponseCommentDto>> CommentMap = nwret.getData().stream().collect(Collectors.groupingBy(ResponseCommentDto::getProcessInstanceId));

            // 结果类型转换
            List<DemandManagementDto> retdata = new ArrayList<DemandManagementDto>();
            for (ResponseSituationDto r : list) {

                DemandManagementDto nr = DemandManagementDto.instance(r);


                //调用网关接口查询具体要素信息
                FlowableDemandDto demandinfoDto = demandDtoMap.get(r.getProcessId());
                if (demandinfoDto != null) {
                    FlowableResponse<FlowableDemandDto> demandinfo = new FlowableResponse<FlowableDemandDto>(0, "", demandinfoDto);
                    if (demandinfo.getStatus() == 0) {
                        nr.setRqUgtLevel(demandinfo.getData().getDemandEmergeLevel() != null ? RqUgtLevel.getRqUgtLevel(demandinfo.getData().getDemandEmergeLevel()) : null);
                        if (!Strings.isNullOrEmpty(demandinfo.getData().getArrangeinfo())) {
                            try {
                                List<ArrangeInf> alist = JSONObject.parseArray(demandinfo.getData().getArrangeinfo(), ArrangeInf.class);
                                nr.setArrangeinfo(alist);
                            } catch (Exception e) {
                                logger.error("Arrangeinfo字符串转对象异常，请查看！流程继续。", e);
                            }
                        }
                        if (!Strings.isNullOrEmpty(demandinfo.getData().getOnlineinfo())) {
                            try {
                                List<OnlineInf> olist = JSONObject.parseArray(demandinfo.getData().getOnlineinfo(), OnlineInf.class);
                                nr.setOnlineinfo(olist);
                            } catch (Exception e) {
                                logger.error("OnlineInf字符串转对象异常，请查看！流程继续。", e);
                            }
                        }
                        //获取comments信息

//                    FlowableResponse<PageDataResult<ResponseCommentDto>> nwret = feignDemandService.queryCommentsByProcessId(1, 100, param);
//                    if (nwret.getStatus() == 0) {
//                        nr.setComments(nwret.getData().getList());
//                    }
                        nr.setComments(CommentMap.get(r.getProcessId()));
                    }
                }
                retdata.add(nr);
            }
            ;

            Pageable pageable = PageRequest.of(PageUtil.initPageNo(pageNumber) - 1, PageUtil.initPageSize(pageSize));
            Page<DemandManagementDto> retd = new PageImpl(retdata, pageable, queryflowRet.getData().getTotals());
//            //page包装
//            PageDataResult<DemandManagementDto> retd = PageDataResult.success("", retdata);
//            retd.setTotals(queryflowRet.getData().getTotals());
            return PlatformResponse.successData(retd);

        } catch (Exception e) {
            logger.error("需求管理查询接口异常！", e);
            return PlatformResponse.failedMsg(e.getMessage());
        }
    }


    /**
     * 查询需求完整信息，包括业务要素信息及节点状态信息
     */
    @RequestMapping(method = RequestMethod.GET, value = "getProcessinfo")
    public PlatformResponse<AllProcessInfo> getProcessinfo(@RequestParam(value = "rqId", required = true) String rqId) {
        PlatformResponse<AllProcessInfo> ret;

        try {
            //1.获取流程信息
            FlowableResponse<ResponseSituationDto> processinfo = feignDemandService.getProcessInfo(rqId);
            if (processinfo.getStatus() != 0) {
                return PlatformResponse.failedMsg(processinfo.getMsg());
            }

            //2.获取要素信息
            FlowableResponse<FlowableDemandDto> demandinfo = feignDemandService.getDemandInfo(rqId);
            if (demandinfo.getStatus() != 0) {
                return PlatformResponse.failedMsg(demandinfo.getMsg());
            }

            AllProcessInfo info = new AllProcessInfo();

            //3.分析流程图信息
            //3.1将走过的节点加入AllProcessInfo
            processinfo.getData().getCreatedTaskInfoDtoList().forEach(r -> {
                info.addNode(r);
            });

            //3.2将没有走过的节点加入AllProcessInfo
            for (ProcessNode node : ProcessNode.values()) {
                if (!info.getFlowmap().containsKey(node)) {
                    info.addNullNode(node);
                }
            }

            //要素信息对象转换
            info.setGlRequirement(DemandManagementDto.instance(processinfo.getData(), demandinfo.getData()));

            //获取comments信息
            ParamCommentDto param = new ParamCommentDto();
            param.setProcessId(rqId);
            FlowableResponse<PageDataResult<ResponseCommentDto>> nwret = feignDemandService.queryCommentsByProcessId(1, 100, param);
            info.setComments(nwret.getData().getList());

            ret = PlatformResponse.successData(info);

        } catch (Exception e) {
            ret = PlatformResponse.failedMsg(e.getMessage());
            logger.error("getProcessinfo异常！", e);
        }

        return ret;
    }


    /**
     * 更新需求紧急状态
     */
    @RequestMapping(method = RequestMethod.POST, value = "changeRqUgtLevel")
    public PlatformResponse<?> changeRqLevel(HttpServletRequest request, @RequestBody ChangeRqLevelRequest changeRqLevelReq) {
        PlatformResponse<?> ret;
        try {

            //2.更新级别
            FlowableResponse flowableResponse = feignDemandService.updateEmergeLevel(changeRqLevelReq.getRqId(), changeRqLevelReq.getRqUgtLevel().getNwCode());
            return flowableResponse.getStatus() == 0 ? PlatformResponse.success() : PlatformResponse.failedMsg(flowableResponse.getMsg());
        } catch (Exception e) {
            logger.error("changeRqLevel异常！", e);
            return PlatformResponse.failedMsg(e.getMessage());
        }
    }

    /**
     * 取消流程
     */
    @RequestMapping(method = RequestMethod.POST, value = "stopProcess")
    public PlatformResponse<?> stopProcess(HttpServletRequest request, @RequestBody String rqId) {
        PlatformResponse<?> ret;
        try {
            feignDemandService.stopProcessInstanceById(rqId, null);
            return PlatformResponse.success();
        } catch (Exception e) {
            logger.error("stopProcess异常！", e);
            return PlatformResponse.failedMsg(e.getMessage());
        }
    }


    @RequestMapping(method = RequestMethod.POST, value = "uploadDoc")
    public PlatformResponse<List<Map<String, String>>> uploadDoc(HttpServletRequest request, @RequestPart(value = "file") MultipartFile[] file) {
        PlatformResponse<List<Map<String, String>>> ret;
        try {
            //1.调用网关系统上传文件
            FlowableResponse<ResponseUploadDto> nwret = feignDemandService.uploadDoc(file);
            if (nwret.getStatus() == 0) {
                //"annexId": "http://10.1.81.200:12580/flowable/common/oaDownloadAppendix/ee7ded5a-2198-4d56-a44d-b2af055e227d",
                //"annexName": "需求测试文档.docx"
                List<Map<String, String>> list = nwret.getData().getFileList();
                list.forEach(r -> {
                    r.put("annexId", r.get("annexId").substring(r.get("annexId").lastIndexOf("/") + 1));
                });
                return PlatformResponse.successData(list);
            } else {
                return PlatformResponse.failedMsg(nwret.getMsg());
            }
        } catch (Exception e) {
            logger.error("uploadDoc异常！", e);
            return PlatformResponse.failedMsg(e.getMessage());
        }
    }


    @RequestMapping(method = RequestMethod.GET, value = "downloadDoc")
    public PlatformResponse<byte[]> downloadDoc(@RequestParam(value = "appendixId", required = true) String appendixId) {
        PlatformResponse<byte[]> ret;

        try {
            ResponseEntity<byte[]> nwret = feignDemandService.downloadDemandAppendix(appendixId);
            if (nwret != null) {
                ret = PlatformResponse.successData(nwret.getBody());
            } else {
                ret = PlatformResponse.failedMsg("文件下载失败");
            }

        } catch (Exception e) {
            ret = PlatformResponse.failedMsg(e.getMessage());
            logger.error("downloadDoc异常！", e);
        }

        return ret;
    }

    @RequestMapping(method = RequestMethod.GET, value = "showDoc")
    public PlatformResponse<ReportShowResponse> show(@RequestParam(value = "appendixId", required = true) String appendixId,
                                                     @RequestParam(value = "appendixName", required = true) String appendixName) {
        PlatformResponse<ReportShowResponse> ret;
        try {
            String title = appendixName;
            String url = downloadUrl + appendixId;
            String token = tokenUtil.generateToken(JsonUtil.Obj2Str(new ReportShowResponse(title, url, FileType.valueOf(appendixName.substring(appendixName.lastIndexOf(".") + 1)))));

            ReportShowResponse resdata = new ReportShowResponse(title, url, token, FileType.valueOf(appendixName.substring(appendixName.lastIndexOf(".") + 1)));
            ret = PlatformResponse.successData(resdata);
            ret.setFileId(title);
        } catch (Exception e) {
            ret = PlatformResponse.failedMsg(e.getMessage());
        }

        return ret;
    }


}
